#include "log.h"
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "hirestime.h"

#if   defined(_MSC_VER) && (_MSC_VER>1000)
#pragma warning(disable:996 267)
#endif

FILE*       g_log = NULL;
unsigned    g_filetype = RAYLOG_TYPE_UNKNOW;
unsigned    g_timetype = RAYLOG_TIME_RELATIVE;
unsigned    g_itemcolor = 0;

unsigned g_enabled = 1;

void _loadHtmlInc();
void _write(char* content);
void _processStr(char* content, unsigned fmttype, unsigned level, char* dest);

extern void _writeHtml(char* content, unsigned type);
extern void _cwriteHtml(char* content, unsigned type, unsigned cltype);

extern void _writeSTD(char* content, unsigned type);
extern void _cwriteSTD(char* content, unsigned type, unsigned cltype);



// Create a log file
void log_init(char* filename, unsigned type)
{
    assert(filename);
    assert( RAYLOG_TYPE_UNKNOW < type && RAYLOG_TYPE_MAX >= type);

    HRTInit();
    g_log = fopen(filename, "w");
    g_filetype = type;

    if (type & RAYLOG_TYPE_HTML)
    {
        _write("<HTML>");
        _loadHtmlInc();
        return;
    }
    if (type & RAYLOG_TYPE_STD)
        return;
}

void _replaceNL(char*content, char* dest)
{
    char* buff = dest;
    int i, indexs = 0, indexd = 0;

    for(i=0; (unsigned)i<strlen(content); i++, indexd++, indexs++)
    {
        if (content[i] == '\n')
        {
            buff[indexd] = '<';
            buff[++indexd] = 'b';
            buff[++indexd] = 'r';
            buff[++indexd] = '>';
        }
        else
            buff[indexd] = content[indexs];
    }
    buff[indexd] = '\0';
}

void log_enable()
{
    g_enabled = 1;
}

void log_disable()
{
    g_enabled = 0;
}

void log_write(char* content, unsigned fmttype, unsigned level)
{
    char buff[RAYLOG_MAXSTR];
    char buffHTML[RAYLOG_MAXSTR];

    _processStr(content, fmttype, level, buff);
    if (g_filetype & RAYLOG_TYPE_HTML)
    {
        _replaceNL(buff, buffHTML);
        _writeHtml(buffHTML, fmttype);
    }
    if (g_filetype & RAYLOG_TYPE_STD)
        _writeSTD(buff, fmttype);
}

void log_cwrite(char* content, unsigned fmttype, unsigned level, unsigned cltype)
{
    char buff[RAYLOG_MAXSTR];
    char buffHTML[RAYLOG_MAXSTR];
    assert(g_filetype & RAYLOG_TYPE_HTML);

    _processStr(content, fmttype, level, buff);
    if (g_filetype & RAYLOG_TYPE_HTML)
    {
        _replaceNL(buff, buffHTML);
        _cwriteHtml(buffHTML, fmttype, cltype);
    }
    if (g_filetype & RAYLOG_TYPE_STD)
        _cwriteSTD(buff, fmttype, cltype);
}

void log_flush()
{
    assert(g_log);
    fflush(g_log);
}

// Release used resources
void log_destory()
{
    assert(g_log);
    
    log_flush();
    switch (g_filetype)
    {
    case(RAYLOG_TYPE_HTML):
        _write("</HTML>");
        break;
    case(RAYLOG_TYPE_STD):
        break;
    }

    fclose(g_log);
}

void log_setTimeType(unsigned timetype)
{
    g_timetype = timetype;
}

void _write(char* content)
{
    CHECK_ENABLE();
    fprintf(g_log, "%s", content);
}

// add time and leve infomation to the str
void _processStr(char* content, unsigned fmttype, unsigned level, char* dest)
{
    char* buff = dest;

    double time = HRTNowSec();

    assert(g_log);
    assert(content);

    if (fmttype == RAYLOG_TITLE || fmttype == RAYLOG_SUBHEADER
        || fmttype == RAYLOG_HEADER || level == 0)
        sprintf(buff, "%s", content); //nbsp
    else
        sprintf(buff, "[%d @ %fs] %s", level, (double)time, content); //nbsp
}
